#ifndef _MODULE_H_INCLUDED_
#define _MODULE_H_INCLUDED_


#include <string>
using std::string;
#if 0
struct module_t
{
    string name;
    std::function<void()> handler;
    template<typename F, typename... Args>
    module_t(string _name, F&& functor, Args&&... args):
    name(_name), handler(std::bind(std::forward<F>(functor), std::forward<Args>(args)...)){}
    module_t(const module_t&) = default;
};


void test(int a, int b){
	//cout << "test succeeded!" << endl;
    return;
}

class module
{
private:
    std::unordered_map<string, module_t*> modules;   
    void addModule(module_t& theModule);
public:
    module(std::list<module_t>& moduleList){
        using it_t = std::list<module_t>::iterator;
        if(moduleList.empty()){
            std::runtime_error("invalid module list!");
        }
        for(it_t temp = moduleList.begin(); temp != moduleList.end(); temp++){
            addModule(*temp);
        }
    }
    module() = delete;
    module(const module&) = delete;
    module& operator= (const module&) = delete;
    module_t* getModuleByName(const string& moduleName);
    ~module() = default;
};

void module::addModule(module_t& theModule)
{
    modules.emplace(theModule.name, &theModule);
}

module_t* module::getModuleByName(const string& moduleName)
{
    using it_t = std::unordered_map<string, module_t*>::iterator;
    it_t theModule = modules.find(moduleName);
    if(theModule == modules.end())
        return NULL;
    else{
        return theModule->second;
    }
}

#endif

class module_base{
public:
    string module_name;
    virtual void handler() = 0;
    module_base(const char* moduleName):
    module_name(moduleName){}
};

#endif